
#include "System.h"


namespace
{
    struct Inst
    {
        static std::string SaveDialog(const std::string &title, const System::Filters &filters, const std::string &defaultFilename, std::string submitBtn, std::string cancelBtn)
        {
            GtkWidget *dialog;
            GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

            std::string savePath;

            dialog = gtk_file_chooser_dialog_new(title.c_str(),
                                                 GTK_WINDOW(window),
                                                 GTK_FILE_CHOOSER_ACTION_SAVE,
                                                 cancelBtn.c_str(), GTK_RESPONSE_CANCEL,
                                                 submitBtn.c_str(), GTK_RESPONSE_ACCEPT,
                                                 NULL);

            gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);

            gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), defaultFilename.c_str());

            for (const auto &it : filters.m_Filters)
            {

                GtkFileFilter *filter = gtk_file_filter_new();
                gtk_file_filter_set_name(filter, it.m_Name.c_str());

                for (auto p : it.m_Patterns)
                {
                    gtk_file_filter_add_pattern(filter, p.c_str());
                }

                gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
            }

            gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), defaultFilename.c_str());

            if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
            {
                GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
                char *filename = gtk_file_chooser_get_filename(chooser);
                if (filename)
                {
                    savePath = filename;
                    g_free(filename);
                }
            }
            gtk_widget_destroy(dialog);
            return savePath;
        };

        static std::string OpenDialog(const std::string &title, const System::Filters &filters, std::string submitBtn, std::string cancelBtn)
        {
            std::string selectedFile;
            GtkWidget *dialog;
            GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

            dialog = gtk_file_chooser_dialog_new(title.c_str(),
                                                 GTK_WINDOW(window),
                                                 GTK_FILE_CHOOSER_ACTION_SAVE,
                                                 cancelBtn.c_str(), GTK_RESPONSE_CANCEL,
                                                 submitBtn.c_str(), GTK_RESPONSE_ACCEPT,
                                                 NULL);

            for (const auto &it : filters.m_Filters)
            {
                GtkFileFilter *filter = gtk_file_filter_new();
                gtk_file_filter_set_name(filter, it.m_Name.c_str());

                for (auto p : it.m_Patterns)
                {
                    gtk_file_filter_add_pattern(filter, p.c_str());
                }

                gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
            }
            if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
            {
                GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
                char *filename = gtk_file_chooser_get_filename(chooser);
                if (filename)
                {
                    selectedFile = filename;
                    g_free(filename);
                }
            }
            gtk_widget_destroy(dialog);

            return selectedFile;
        }
    };
}

void System::Init(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
}

std::string System::OpenDialog(const std::string &title, const Filters &filters, std::string submitBtn, std::string cancelBtn){

    std::future<std::string> futureResult = std::async(std::launch::async, Inst::OpenDialog, title, filters, submitBtn, cancelBtn);
    return futureResult.get();
};

std::string System::SaveDialog(const std::string &title, const Filters &filters, const std::string &defaultFilename, std::string submitBtn, std::string cancelBtn)
{

    std::future<std::string> futureResult = std::async(std::launch::async, Inst::SaveDialog, title, filters, defaultFilename, submitBtn, cancelBtn);
    return futureResult.get();
};
